// compile: g++ -o atomic atomic.cc -std=c++11
// run: ./atomic
#include <unistd.h>

#include <atomic>
#include <iostream>
#include <thread>
using namespace std;
// 获得是一个对内存的读操作，当前线程的任何后面的读写操作都不允许重排到这个操作的前面去。
// 释放是一个对内存的写操作，当前线程的任何前面的读写操作都不允许重排到这个操作的后面去。

// 对于atomic变量而言:
// y = 2 相当于 y.store(2, memory_order_release)
// y == 2 相当于 y.load(memory_order_acquire) == 2

// acquire 和 release 通常都是配对出现的，
// 目的是保证如果对同一个原子对象的 release 发生在 acquire 之前的话，release
// 之前发生的内存修改能够被 acquire 之后的内存读取全部看到。
atomic<int> x;
atomic<int> y;
void func1() {
  // sleep(1);
  // x = 1;
  x.store(1, std::memory_order_relaxed);
  y.store(2, std::memory_order_release);
}
void func2() {
  // if (y == 2) {
  if (y.load(std::memory_order_acquire) == 2) {
    //  x = 3;
    x.store(3, std::memory_order_relaxed);
    // y = 4;
    y.store(4, std::memory_order_relaxed);
  }
}
void Test1() {
  thread t1(func1);
  thread t2(func2);
  t1.join();
  t2.join();
  cout << "x=" << x << endl;
  cout << "y=" << y << endl;
}
void Test2() {}
int main() {
  Test1();
  Test2();
  return 0;
}
